<?php

/**
 * Représente une pagination
 *
 * @package cass
 * @author Mickaël CASTANHEIRO <mickael.castanheiro@gmail.com>
 * @version 1.0
 */

namespace cass;

use \Doctrine\ORM\Query;

class Pagination extends Element {

    protected $currentPage;
    protected $nbByPage;
    protected $nbElements;
    protected $nbPages;
    protected $query;
    protected $uri;

    /**
     * Constructeur de pagination
     * @param Query $_query Requête à effectuer pour les éléments à afficher
     */
    public function __construct(Query $_query) {
	FrontController::getInstance()->getParameters()->addToCss('cass-page'); // Fichier css lié à la pagination
	FrontController::getInstance()->getParameters()->addToCss('pagination'); // Fichier css lié à la pagination
	$this->query = $_query;
	$this->nbByPage = 10;
	$this->currentPage = 1;
	$this->url = new Uri;
    }

    /**
     * Url de la page en cours
     * @param Uri $_uri
     */
    public function setUri() {
	$this->uri = call_user_func_array(array('\cass\Uri', 'create'), func_get_args());
    }

    /**
     * Compte le nombre d'éléments de la requête
     * @return <integer> Nombre d'éléments dans la requête
     */
    public function count() {
	/* @var $countQuery Query */
	$countQuery = clone $this->query;
	$countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('\DoctrineExtension\CountSqlWalker'));
	$countQuery->setParameters($this->query->getParameters());
	$countQuery->setFirstResult(null)->setMaxResults(null);
	return $countQuery->getSingleScalarResult();
    }

    /**
     * Modifie la page courante 
     * @param <integer> $_page Page courante
     */
    public function setCurrentPage($_page) {
	if (empty($_page) OR ($_page == 0)) {
	    $_page = 1;
	}
	$this->currentPage = $_page;
    }

    /**
     * Renvoie les éléments de la page
     * @return <QueryResult> Résultat de la requête
     */
    public function getElements() {
	$this->nbElements = $this->count();
	$this->nbPages = ceil($this->nbElements / $this->nbByPage);

	$firstResult = ($this->currentPage - 1) * $this->nbByPage;

	return $this->query->setFirstResult($firstResult)
		->setMaxResults($this->nbByPage)
		->getResult();
    }

    /**
     * La page courante est-elle la première ?
     * @return <boolean>
     */
    public function isFirstPage() {
	return ($this->currentPage == 1);
    }

    /**
     * La page courante est-elle la dernière ?
     * @return <boolean>
     */
    public function isLastPage() {
	return ($this->currentPage == $this->nbPages);
    }

    /**
     * Retourne la page précédente
     * @return <integer> Page précédente
     */
    public function getPreviousPage() {
	return ($this->currentPage > 1 ) ?
		$this->currentPage - 1 :
		1;
    }

    /**
     * Retourne la page suivante
     * @return <integer> Page suivante
     */
    public function getNextPage() {
	return ($this->currentPage < $this->nbPages ) ?
		$this->currentPage + 1 :
		$this->nbPages;
    }

    /**
     * Affiche le rendu de la pagination
     */
    public function render() {
	$template = new \cass\Template;
	$template->setName('_pagination');
	$template->setVars(array(
	    'currentPage' => $this->getCurrentPage(),
	    'nbByPage' => $this->getNbByPage(),
	    'nbElements' => $this->getNbElements(),
	    'nbPages' => $this->getNbPages(),
	    'isFirstPage' => $this->isFirstPage(),
	    'isLastPage' => $this->isLastPage(),
	    'previousPage' => $this->getPreviousPage(),
	    'nextPage' => $this->getNextPage(),
	    'uri' => $this->getUri()
	));

	$template->render();
    }

}